﻿using System;
using GeoAPI.Geometries;

namespace NetTopologySuite.LinearReferencing
{
	public class LengthIndexedLine
	{
		public LengthIndexedLine(IGeometry linearGeom)
		{
			this._linearGeom = linearGeom;
		}

		public Coordinate ExtractPoint(double index)
		{
			return LengthLocationMap.GetLocation(this._linearGeom, index).GetCoordinate(this._linearGeom);
		}

		public Coordinate ExtractPoint(double index, double offsetDistance)
		{
			LinearLocation linearLocation = LengthLocationMap.GetLocation(this._linearGeom, index).ToLowest(this._linearGeom);
			return linearLocation.GetSegment(this._linearGeom).PointAlongOffset(linearLocation.SegmentFraction, offsetDistance);
		}

		public IGeometry ExtractLine(double startIndex, double endIndex)
		{
			new LocationIndexedLine(this._linearGeom);
			double num = this.ClampIndex(startIndex);
			double num2 = this.ClampIndex(endIndex);
			bool resolveLower = num == num2;
			LinearLocation start = this.LocationOf(num, resolveLower);
			LinearLocation end = this.LocationOf(num2);
			return ExtractLineByLocation.Extract(this._linearGeom, start, end);
		}

		private LinearLocation LocationOf(double index)
		{
			return LengthLocationMap.GetLocation(this._linearGeom, index);
		}

		private LinearLocation LocationOf(double index, bool resolveLower)
		{
			return LengthLocationMap.GetLocation(this._linearGeom, index, resolveLower);
		}

		public double IndexOf(Coordinate pt)
		{
			return LengthIndexOfPoint.IndexOf(this._linearGeom, pt);
		}

		public double IndexOfAfter(Coordinate pt, double minIndex)
		{
			return LengthIndexOfPoint.IndexOfAfter(this._linearGeom, pt, minIndex);
		}

		public double[] IndicesOf(IGeometry subLine)
		{
			LinearLocation[] array = LocationIndexOfLine.IndicesOf(this._linearGeom, subLine);
			return new double[]
			{
				LengthLocationMap.GetLength(this._linearGeom, array[0]),
				LengthLocationMap.GetLength(this._linearGeom, array[1])
			};
		}

		public double Project(Coordinate pt)
		{
			return LengthIndexOfPoint.IndexOf(this._linearGeom, pt);
		}

		public double StartIndex
		{
			get
			{
				return 0.0;
			}
		}

		public double EndIndex
		{
			get
			{
				return this._linearGeom.Length;
			}
		}

		public bool IsValidIndex(double index)
		{
			return index >= this.StartIndex && index <= this.EndIndex;
		}

		public double ClampIndex(double index)
		{
			double num = this.PositiveIndex(index);
			double startIndex = this.StartIndex;
			if (num < startIndex)
			{
				return startIndex;
			}
			double endIndex = this.EndIndex;
			if (num > endIndex)
			{
				return endIndex;
			}
			return num;
		}

		private double PositiveIndex(double index)
		{
			if (index >= 0.0)
			{
				return index;
			}
			return this._linearGeom.Length + index;
		}

		private readonly IGeometry _linearGeom;
	}
}
